﻿#include<iostream>
using namespace std;
#include <string>
#include <fstream>

struct node {
public:
	string name;
	struct node* next = NULL;
};

int** b = NULL;
int  c;
struct node* a = NULL;
int j = -1;
void order(struct node* a, int** b)
{
	int* num = new int[c];
	string* pri = new string[c];
	int r = 0;
	for (int i = 0; i < c; i++) pri[i] = "";

	for (int k = 0; k < c; k++)
	{
		//cout << "k = " << k << endl;
		for (int i = 0; i < c; i++) num[i] = 0;
		for (int i = 0; i < c; i++)//计算每个元素的入度
			for (int j = 0; j < c; j++) num[i] = num[i] + b[j][i];
		/*for (int i = 0; i < c; i++) cout << num[i] << " ";
		cout << endl;*/
		if (num[k] == 0)//拓扑排序，入度为0则输出
		{
			//cout << "k=" << k << endl;
			int temp = 0;
			for (int i = 0; i < r + 1; i++)
			{
				if (a[k].name == pri[i])
				{
					temp = 1;
					break;
				}
			}
			if (temp == 0)
			{
				pri[r] = a[k].name;
				r++;
			}
			struct node* q = a[k].next;
			while (q != NULL) {
				int temp1 = 0;
				for (int i = 0; i < r + 1; i++)
				{
					if (q->name == pri[i])
					{
						temp1 = 1;
						break;
					}
				}
				if (temp1 == 0)
				{
					pri[r] = q->name;
					r++;
				}
				q = q->next;
			}
			
			b[k][k]--;
			for (int i = 0; i < c; i++) if (b[k][i] > 0) b[k][i]--;
			k = -1;
		}	
		
	}
	//for (int i = 0; i < c; i++)
	//{
	//	for (int j = 0; j < c; j++) cout << b[i][j] << " ";
	//	cout << endl;
	//}
	int flag = 0;
	for (int i = 0; i < c; i++)
	{
		if (num[i] != -1)
		{
			flag = 1;
			break;
		}
	}
	if (flag == 0)
	{
		cout << "根据数据所得该样例排名估计为：";
		for (int i = 0; i < c; i++)
		{
			cout << pri[i] << " ";
		}
	}
	else cout << "该数据样例矛盾，无法排名！";

}
void seta1(string tk2)
{
	string t = tk2;
	a = new struct node[c];
	for (int i = 0; i < c; i++) {
		a[i].next = NULL;
	}
	int cnt = 0;
	int pos = 0;
	for (int i = 0; ; i++)
	{
		string t1;
		string t2;
		if (t[i] == '>' || t[i] == '<' || t[i] == ',' || t[i] == '=')
		{
			if (t[i] == '>' || t[i] == '<')
			{
				t1 = t.substr(pos, i - pos);
				if (t[i] =='>'||t[i]=='<') 
				{
					t1 = t.substr(pos, i - pos);
					int falg = 0;
					int k;
					for (int i = 0; i <= j; i++)
					{
						if (a[i].name == t1) {
							falg = 1;
							break;
						}
					}
					for (k = i + 1;; k++)
					{
						if (t[k] == ',' || t[k] == '\0')
						{
							t2 = t.substr(i + 1, k - i - 1);
							break;
						}
					}
					int flag1=0;
					for (int i = 0; i <= j; i++)
					{
						if (a[i].name == t2) {
							flag1 = 1;
							break;
						}
					}
					if (falg == 0) 
					{
						j++;
						a[j].name = t1;
						a[j].next = NULL;	
					}
					if (flag1 == 0)
					{
						j++;
						a[j].name = t2;
						a[j].next = NULL;
					}
				}
			}
			pos = i + 1;
		}
		else if (t[i] == '\0') break;
		
	}
}
void seta2(string tk2) {
	string t = tk2;
	int cnt = 0;
	int pos = 0;
	for (int i = 0; ; i++)
	{
		string t1;
		string t2;
		if (t[i] == '>' || t[i] == '<' || t[i] == ',' || t[i] == '=')
		{
			if (t[i] == '=') {
				t1 = t.substr(pos, i - pos);
				int falg = 0;
				for (int i = 0; i <= j; i++) {
					if (a[i].name == t1) {
						falg = 1;
						break;
					}
				}
				if (falg == 0) {
					j++;
					a[j].name = t1;
					a[j].next = NULL;
				}
				if (t[i] == '=') {
					struct node* q = new struct node;
					int q2;
					for (q2 = i + 1; ; q2++) {
						if (t[q2] == ',' || t[q2] == '\0') {
							break;
						}
					}
					t2 = t.substr(i + 1, q2 - i - 1);
					q->name = t2;
					q->next = a[j].next;
					a[j].next = q;
				}
				else if (falg == 1 && t[i] == '=') {
					int k;
					for (k = 0; k < c; k++) {
						if (a[k].name == t1) {
							break;
						}
					}
					struct node* q = new struct node;
					int q1;
					for (q1 = i + 1; ; q1++) {
						if (t[q1] == ',' || t[q1] == '\0') {
							break;
						}
					}
					q->name = t.substr(i + 1, q1 - i - 1);
					q->next = a[k].next;
					a[k].next = q;
				}
				int falg1 = 0;
				for (int i = 0; i <= j; i++) {
					if (a[i].name == t2) {
						falg1 = 1;
						break;
					}
				}
				if (falg1 == 0) {
					j++;
					a[j].name = t2;
					a[j].next = NULL;
					if (t[i] == '=') {
						struct node* q = new struct node;
						int q2;
						for (q2 = i + 1; ; q2++) {
							if (t[q2] == ',' || t[q2] == '\0') {
								break;
							}
						}
						q->name = t1;
						q->next = a[j].next;
						a[j].next = q;
					}
				}
				else if (falg1 == 1 && t[i] == '=') {
					int k;
					for (k = 0; k < c; k++) {
						if (a[k].name == t2) {
							break;
						}
					}
					struct node* q1 = new struct node;
					q1->name = t1;
					q1->next = a[k].next;
					a[k].next = q1;
				}
			}
			pos = i + 1;
		}
		else if (t[i] == '\0')
		{
			t1 = t.substr(pos, i - pos);
			int falg = 0;
			for (int i = 0; i <= j; i++) {
				if (a[i].name == t1) {
					falg = 1;
					break;
				}
			}
			if (falg == 0) {
				j++;
				a[j].name = t1;
				a[j].next = NULL;
			}
			break;
		}
	}
}
void setb(string tk2) {
	string t = tk2;
	int cnt = 0;
	int j = -1;
	b = new int* [c];
	for (int i = 0; i < c; i++) {
		b[i] = new int[c];
	}
	for (int i = 0; i < c; i++) {
		for (int j = 0; j < c; j++) {
			b[i][j] = 0;
		}
	}
	int pos = 0;
	for (int i = 0;; i++)
	{
		string t1, t2;
		int j, k, l;
		if (t[i] == '>' || t[i] == '<')
		{
			t1 = t.substr(pos, i - pos);
			for (j = 0; j < c; j++) if (t1 == a[j].name) break;
			for (k = i + 1;; k++)
			{
				if (t[k] == ',' || t[k] == '\0')
				{
					t2 = t.substr(i + 1, k - i - 1);
					break;
				}
			}
			for (l = 0; l < c; l++) if (t2 == a[l].name) break;

			if (t[i] == '>') b[j][l]++;
			else if (t[i] == '<') b[l][j]++;
			pos = i + 1;
		}
		else if (t[i] == ',') pos = i + 1;
		else if (t[i] == '\0') break;
	}
}
int main()
{
	ifstream ifs1;
	ifs1.open("order.txt", ios::in);
	if (!ifs1.is_open())
	{
		cout << "打开失败" << endl;
		return 0;
	}
	for (int i = 0; i < 3; i++) {
		string t, t1, t2;
		getline(ifs1, t1);
		while (t1[0] != '\0') {
			t += t1;
			t += ',';
			getline(ifs1, t1);
		}
		c = t[0] - 48;
		j = -1;
		t2 = t.substr(2, t.length() - 3);
		seta1(t2);
		seta2(t2);
		setb(t2);
		order(a, b);
		cout << endl;
	}
	return 0;
}